<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>part2_7_arm_power_modelling - learning-gem5</title>
        <!-- Custom HTML head -->
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff" />

        <link rel="icon" href="../favicon.svg">
        <link rel="shortcut icon" href="../favicon.png">
        <link rel="stylesheet" href="../css/variables.css">
        <link rel="stylesheet" href="../css/general.css">
        <link rel="stylesheet" href="../css/chrome.css">
        <link rel="stylesheet" href="../css/print.css" media="print">
        <!-- Fonts -->
        <link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="../fonts/fonts.css">
        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="../highlight.css">
        <link rel="stylesheet" href="../tomorrow-night.css">
        <link rel="stylesheet" href="../ayu-highlight.css">

        <!-- Custom theme stylesheets -->
    </head>
    <body>
        <!-- Provide site root to javascript -->
        <script type="text/javascript">
            var path_to_root = "../";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script type="text/javascript">
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script type="text/javascript">
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('no-js')
            html.classList.remove('light')
            html.classList.add(theme);
            html.classList.add('js');
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script type="text/javascript">
            var html = document.querySelector('html');
            var sidebar = 'hidden';
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            }
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item expanded affix "><a href="../part0_introduction.html">Learning gem-5</a></li><li class="chapter-item expanded "><a href="../part0_introduction.html"><strong aria-hidden="true">1.</strong> part0_introduction</a></li><li class="chapter-item expanded "><a href="../part1/part1_1_building.html"><strong aria-hidden="true">2.</strong> part1</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../part1/part1_1_building.html"><strong aria-hidden="true">2.1.</strong> part1_1_building</a></li><li class="chapter-item expanded "><a href="../part1/part1_2_simple_config.html"><strong aria-hidden="true">2.2.</strong> part1_2_simple_config</a></li><li class="chapter-item expanded "><a href="../part1/part1_3_cache_config.html"><strong aria-hidden="true">2.3.</strong> part1_3_cache_config</a></li><li class="chapter-item expanded "><a href="../part1/part1_4_gem5_stats.html"><strong aria-hidden="true">2.4.</strong> part1_4_gem5_stats</a></li><li class="chapter-item expanded "><a href="../part1/part1_5_gem5_example_configs.html"><strong aria-hidden="true">2.5.</strong> part1_5_gem5_example_configs</a></li><li class="chapter-item expanded "><a href="../part1/part1_6_extending_configs.html"><strong aria-hidden="true">2.6.</strong> part1_6_extending_configs</a></li></ol></li><li class="chapter-item expanded "><a href="../part2/part2_0_environment.html"><strong aria-hidden="true">3.</strong> part2</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../part2/part2_0_environment.html"><strong aria-hidden="true">3.1.</strong> part2_0_environment</a></li><li class="chapter-item expanded "><a href="../part2/part2_1_helloobject.html"><strong aria-hidden="true">3.2.</strong> part2_1_helloobject</a></li><li class="chapter-item expanded "><a href="../part2/part2_2_debugging.html"><strong aria-hidden="true">3.3.</strong> part2_2_debugging</a></li><li class="chapter-item expanded "><a href="../part2/part2_3_events.html"><strong aria-hidden="true">3.4.</strong> part2_3_events</a></li><li class="chapter-item expanded "><a href="../part2/part2_4_parameters.html"><strong aria-hidden="true">3.5.</strong> part2_4_parameters</a></li><li class="chapter-item expanded "><a href="../part2/part2_5_memoryobject.html"><strong aria-hidden="true">3.6.</strong> part2_5_memoryobject</a></li><li class="chapter-item expanded "><a href="../part2/part2_6_simplecache.html"><strong aria-hidden="true">3.7.</strong> part2_6_simplecache</a></li><li class="chapter-item expanded "><a href="../part2/part2_7_arm_power_modelling.html" class="active"><strong aria-hidden="true">3.8.</strong> part2_7_arm_power_modelling</a></li><li class="chapter-item expanded "><a href="../part2/part2_8_arm_dvfs_support.html"><strong aria-hidden="true">3.9.</strong> part2_8_arm_dvfs_support</a></li></ol></li><li class="chapter-item expanded "><a href="../part3/part3_00_MSIntro.html"><strong aria-hidden="true">4.</strong> part3</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../part3/part3_00_MSIntro.html"><strong aria-hidden="true">4.1.</strong> part3_00_MSIntro</a></li><li class="chapter-item expanded "><a href="../part3/part3_01_cache-intro.html"><strong aria-hidden="true">4.2.</strong> part3_01_cache-intro</a></li><li class="chapter-item expanded "><a href="../part3/part3_02_cache-declarations.html"><strong aria-hidden="true">4.3.</strong> part3_02_cache-declarations</a></li><li class="chapter-item expanded "><a href="../part3/part3_03_cache-in-ports.html"><strong aria-hidden="true">4.4.</strong> part3_03_cache-in-ports</a></li><li class="chapter-item expanded "><a href="../part3/part3_04_cache_actions.html"><strong aria-hidden="true">4.5.</strong> part3_04_cache_actions</a></li><li class="chapter-item expanded "><a href="../part3/part3_05_cache_transitions.html"><strong aria-hidden="true">4.6.</strong> part3_05_cache_transitions</a></li><li class="chapter-item expanded "><a href="../part3/part3_06_directory.html"><strong aria-hidden="true">4.7.</strong> part3_06_directory</a></li><li class="chapter-item expanded "><a href="../part3/part3_07_MSIbuilding.html"><strong aria-hidden="true">4.8.</strong> part3_07_MSIbuilding</a></li><li class="chapter-item expanded "><a href="../part3/part3_08_configuration.html"><strong aria-hidden="true">4.9.</strong> part3_08_configuration</a></li><li class="chapter-item expanded "><a href="../part3/part3_09_running.html"><strong aria-hidden="true">4.10.</strong> part3_09_running</a></li><li class="chapter-item expanded "><a href="../part3/part3_10_MSIdebugging.html"><strong aria-hidden="true">4.11.</strong> part3_10_MSIdebugging</a></li><li class="chapter-item expanded "><a href="../part3/part3_11_simple-MI_example.html"><strong aria-hidden="true">4.12.</strong> part3_11_simple-MI_example</a></li></ol></li><li class="chapter-item expanded "><a href="../part4_gem5_101.html"><strong aria-hidden="true">5.</strong> part4_gem5_101</a></li><li class="chapter-item expanded "><a href="../http://doxygen.gem5.org/develop/index.html"><strong aria-hidden="true">6.</strong> part4_gem5_102</a></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
        </nav>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky bordered">
                    <div class="left-buttons">
                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </button>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">learning-gem5</h1>

                    <div class="right-buttons">
                        <a href="../print.html" title="Print this book" aria-label="Print this book">
                            <i id="print-button" class="fa fa-print"></i>
                        </a>
                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>
                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script type="text/javascript">
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <h1 id="arm-电源建模"><a class="header" href="#arm-电源建模">ARM 电源建模</a></h1>
<p>可以对 gem5 模拟的能量和功率使用进行建模和监控。这是通过使用 gem5 已经记录在<code>MathExprPowerModel</code>中的各种统计数据来完成的；<code>MathExprPowerModel</code>是一种通过数学方程对电力使用进行建模的方法。本教程的这一章详细介绍了电源建模所需的各种组件，并说明了如何将它们添加到现有的 ARM 仿真中。</p>
<p>本章借鉴了<code>configs/example/arm</code>目录中提供的配置脚本<code>fs_power.py</code>，还提供了如何扩展此脚本或其他脚本的说明。</p>
<p>请注意，只有在使用更详细的“时序”CPU 时才能应用电源模型。</p>
<p>在 2017 年 ARM 研究峰会上<a href="https://youtu.be/3gWyUWHxVj4">Sascha Bischoff 的演讲中</a>可以找到有关如何将电源建模内置到 gem5 中以及它们与模拟器的哪些其他部分进行交互的概述。</p>
<h2 id="动态电源状态"><a class="header" href="#动态电源状态">动态电源状态</a></h2>
<p>电源模型由两个函数组成，它们描述了如何计算不同电源状态下的功耗。电源状态是（来自 <code>src/sim/PowerState.py</code>）：</p>
<ul>
<li><code>UNDEFINED</code>: 无效状态，没有可用的电源状态派生信息。此状态是默认状态。</li>
<li><code>ON</code>：逻辑块正在活跃地运行，并根据所需的处理量消耗动态和泄漏能量。</li>
<li><code>CLK_GATED</code>：块内的时钟电路被门控以节省动态能量，块的电源仍然打开并且块消耗泄漏能量。</li>
<li><code>SRAM_RETENTION</code>：逻辑块内的 SRAM 被拉入保持状态以进一步减少泄漏能量。</li>
<li><code>OFF</code>：逻辑块是电源门控的，不消耗任何能量。</li>
</ul>
<p>除了<code>UNDEFINED</code>，使用<code>PowerModel</code>类的<code>pm</code>字段为每个状态分配一个电源模型。它是一个包含 4 个电源模型的列表，每个状态一个，按以下顺序：</p>
<ol>
<li><code>ON</code></li>
<li><code>CLK_GATED</code></li>
<li><code>SRAM_RETENTION</code></li>
<li><code>OFF</code></li>
</ol>
<p>请注意，虽然有 4 个不同的条目，但它们不一定是不同的电源模型。提供的<code>fs_power.py</code>文件为<code>ON</code>状态使用一个电源模型，然后为其余状态使用相同的电源模型。</p>
<h2 id="电源使用类型"><a class="header" href="#电源使用类型">电源使用类型</a></h2>
<p>gem5 模拟器模拟 2 种电源使用类型：</p>
<ul>
<li><strong>static</strong>：无论活动如何，模拟系统使用的功率。</li>
<li><strong>dynamic</strong>：系统因各种类型的活动而使用的功率。</li>
</ul>
<p>功率模型必须包含用于对这两个模型进行建模的方程（尽管该方程可以很简单得像<code>st = &quot;0&quot;</code>，例如，静态功率在该功率模型中是不需要的或不相关的）。</p>
<h2 id="mathexprpowermodels"><a class="header" href="#mathexprpowermodels">MathExprPowerModels</a></h2>
<p><code>fs_power.py</code>中提供的电源模型继承了<code>MathExprPowerModel</code> 类。<code>MathExprPowerModels</code>被指定为包含数学表达式的字符串，用于计算系统使用的功率。它们通常包含统计数据和自动变量的混合，例如温度：</p>
<pre><code class="language-python">class CpuPowerOn(MathExprPowerModel):
    def __init__(self, cpu_path, **kwargs):
        super(CpuPowerOn, self).__init__(**kwargs)
        # 2A per IPC, 3pA per cache miss
        # and then convert to Watt
        self.dyn = &quot;voltage * (2 * {}.ipc + 3 * 0.000000001 * &quot; \
                   &quot;{}.dcache.overall_misses / sim_seconds)&quot;.format(cpu_path,
                                                                    cpu_path)
        self.st = &quot;4 * temp&quot;
</code></pre>
<p>（以上电源模型取自提供的<code>fs_power.py</code>文件。）</p>
<p>我们可以看到自动变量（<code>voltage</code>和<code>temp</code>）不需要路径，而特定于组件的统计信息（CPU 的每周期指令数 <code>ipc</code>）需要。在文件的更下方的<code>main</code>函数中，我们可以看到 CPU 对象具有一个<code>path()</code>函数，该函数返回组件在系统中的“路径”，例如<code>system.bigCluster.cpus0</code>. 该<code>path</code>函数由<code>SimObject</code>系统中的任何对象提供 ，因此可以被系统中扩展它的任何对象使用，例如，l2 缓存对象比 CPU 对象靠后几行使用它。</p>
<p>（注：<code>dcache.overall_misses</code>通过<code>sim_seconds</code>转换为瓦特。这是一个<em>功率</em>模式，即随着时间的推移能量，而不是一个能量模型。使用这些术语时最好小心些，因为它们经常被混用，但当涉及到电力和能源模拟/建模时它们分别指代不同的具体事物。）</p>
<h2 id="扩展现有的模拟"><a class="header" href="#扩展现有的模拟">扩展现有的模拟</a></h2>
<p><code>fs_power.py</code>通过导入和修改数值拓展了现有的<code>fs_bigLITTLE.py</code>脚本。作为其中的一部分，脚本用多个循环遍历 SimObjects 的子类以应用 Power Models。因此，为了扩展现有的仿真以支持功率模型，定义一个辅助函数来执行此操作会很有帮助：</p>
<pre><code class="language-python">def _apply_pm(simobj, power_model, so_class=None):
    for desc in simobj.descendants():
        if so_class is not None and not isinstance(desc, so_class):
            continue

        desc.power_state.default_state = &quot;ON&quot;
        desc.power_model = power_model(desc.path())
</code></pre>
<p>上面的函数采用 SimObject、Power Model 和可选的类，SimObject 的后代必须是<code>so_class</code>的实例才能应用 PM。如果未指定类，则 PM 将应用于所有子类。</p>
<p>无论您决定是否使用辅助函数，您现在都需要定义一些电源模型。这可以通过遵循<code>fs_power.py</code>中的模式来完成 ：</p>
<ol>
<li>为您感兴趣的每个电源状态定义一个类。这些类应该扩展<code>MathExprPowerModel</code>，并包含<code>dyn</code>和<code>st</code> 字段。这些字段中的每一个都应包含一个字符串，描述如何计算此状态下的相应功率类型。它们的构造函数应该包括 <code>format()</code>在描述功率计算方程的字符串中使用的路径(cpu_path)，以及要传递给超类构造函数的多个 kwarg。</li>
<li>定义一个类来保存上一步中定义的所有电源模型（CpuPowerModel）。此类应扩展<code>PowerModel</code>并包含一个字段<code>pm</code>，该字段包含 4 个元素的列表：<code>pm[0]</code>应该是“ON”电源状态的电源模型的实例；<code>pm[1]</code>应该是“CLK_GATED”电源状态的电源模型的实例；等等。这个类的构造函数应该采用传递给单个 Power Models 的路径，以及传递给超类构造函数的多个 kwarg。</li>
<li>定义了辅助函数和上述类后，您可以扩展该<code>build</code>函数以将这些考虑在内，如果您希望能够切换模型的使用，则可以选择在该函数中添加一个命令行标志<code>addOptions</code>。</li>
</ol>
<blockquote>
<p><strong>示例实现：</strong></p>
<pre><code class="language-python">class CpuPowerOn(MathExprPowerModel):
    def __init__(self, cpu_path, **kwargs):
        super(CpuPowerOn, self).__init__(**kwargs)
        self.dyn = &quot;voltage * 2 * {}.ipc&quot;.format(cpu_path)
        self.st = &quot;4 * temp&quot;


class CpuPowerClkGated(MathExprPowerModel):
    def __init__(self, cpu_path, **kwargs):
        super(CpuPowerOn, self).__init__(**kwargs)
        self.dyn = &quot;voltage / sim_seconds&quot;
        self.st = &quot;4 * temp&quot;


class CpuPowerOff(MathExprPowerModel):
    dyn = &quot;0&quot;
    st = &quot;0&quot;


class CpuPowerModel(PowerModel):
    def __init__(self, cpu_path, **kwargs):
        super(CpuPowerModel, self).__init__(**kwargs)
        self.pm = [
            CpuPowerOn(cpu_path),       # ON
            CpuPowerClkGated(cpu_path), # CLK_GATED
            CpuPowerOff(),              # SRAM_RETENTION
            CpuPowerOff(),              # OFF
        ]

[...]

def addOptions(parser):
    [...]
    parser.add_argument(&quot;--power-models&quot;, action=&quot;store_true&quot;,
                        help=&quot;Add power models to the simulated system. &quot;
                             &quot;Requires using the 'timing' CPU.&quot;
    return parser


def build(options):
    root = Root(full_system=True)
    [...]
    if options.power_models:
        if options.cpu_type != &quot;timing&quot;:
            m5.fatal(&quot;The power models require the 'timing' CPUs.&quot;)

        _apply_pm(root.system.bigCluster.cpus, CpuPowerModel
                  so_class=m5.objects.BaseCpu)
        _apply_pm(root.system.littleCluster.cpus, CpuPowerModel)

    return root

[...]
</code></pre>
</blockquote>
<h2 id="统计名称"><a class="header" href="#统计名称">统计名称</a></h2>
<p>统计名称通常与模拟后<code>stats.txt</code>在<code>m5out</code>目录中生成的文件中看到的相同。但是，也有一些例外：</p>
<ul>
<li>CPU 时钟在<code>stats.txt</code>称为<code>clk_domain.clock</code>，但在电源模型中使用<code>clock_period</code>（不是<code>clock</code>）访问。</li>
</ul>
<h2 id="统计转储频率"><a class="header" href="#统计转储频率">统计转储频率</a></h2>
<p>默认情况下，gem5<code>stats.txt</code>每隔模拟秒将模拟统计信息转储到文件中。这可以通过<code>m5.stats.periodicStatDump</code> 函数进行控制，该函数采用以模拟滴答而不是秒为单位的频率来转储统计数据。幸运的是，<code>m5.ticks</code>提供了<code>fromSeconds</code>函数方便转换。</p>
<p>下面是从<a href="https://youtu.be/3gWyUWHxVj4">Sascha Bischoff 的演示</a>幻灯片 16 中获取的统计转储频率如何影响结果分辨率的示例：</p>
<p><img src="part2_7_arm_power_modelling.assets/empowering_the_masses_slide16.png" alt="一张比较不太详细的功率图与更详细的功率图的图片； 1 秒采样间隔与 1 毫秒采样间隔。" /></p>
<p>转储统计信息的频率直接影响可以基于<code>stats.txt</code>文件生成的图形的分辨率。但是，它也会影响输出文件的大小。每隔模拟秒与每个模拟毫秒转储统计数据会使文件大小增加数百倍。因此，想要控制统计转储频率是有意义的。</p>
<p>使用提供的<code>fs_power.py</code>脚本，可以按如下方式实现频率控制：</p>
<pre><code class="language-python">[...]

def addOptions(parser):
    [...]
    parser.add_argument(&quot;--stat-freq&quot;, type=float, default=1.0,
                        help=&quot;Frequency (in seconds) to dump stats to the &quot;
                             &quot;'stats.txt' file. Supports scientific notation, &quot;
                             &quot;e.g. '1.0E-3' for milliseconds.&quot;)
    return parser

[...]

def main():
    [...]
    m5.stats.periodicStatDump(m5.ticks.fromSeconds(options.stat_freq))
    bL.run()

[...]
</code></pre>
<p>然后可以在调用模拟时指定统计转储频率</p>
<pre><code class="language-bash">--stat-freq &lt;val&gt;
</code></pre>
<h2 id="常见问题"><a class="header" href="#常见问题">常见问题</a></h2>
<ul>
<li>使用提供的<code>fs_power.py</code>时 gem5 崩溃，并显示消息<code>fatal: statistic '' (160) was not properly initialized by a regStats() function</code></li>
<li>使用提供的<code>fs_power.py</code>时 gem5 崩溃，并显示消息<code>fatal: Failed to evaluate power expressions: [...]</code></li>
</ul>
<p>这是因为 gem5 的统计框架最近被重构了。获取最新版本的 gem5 源代码并重新构建应该可以解决问题。如果这是不可行的，则需要以下两组补丁：</p>
<ol>
<li>https://gem5-review.googlesource.com/c/public/gem5/+/26643</li>
<li>https://gem5-review.googlesource.com/c/public/gem5/+/26785</li>
</ol>
<p>可以按照各自链接中的下载说明进行检查和应用。</p>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                            <a rel="prev" href="../part2/part2_6_simplecache.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>
                            <a rel="next" href="../part2/part2_8_arm_dvfs_support.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>
                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                    <a rel="prev" href="../part2/part2_6_simplecache.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>
                    <a rel="next" href="../part2/part2_8_arm_dvfs_support.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
            </nav>

        </div>

        <script type="text/javascript">
            window.playground_copyable = true;
        </script>
        <script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
        <script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
        <script src="../book.js" type="text/javascript" charset="utf-8"></script>

        <!-- Custom JS scripts -->
    </body>
</html>
